import axios from 'axios'
import { IPair } from '~/models/IPairTxData'
import config from '~/config'

const UNI_GRAPH_NODE = config.uni_graph_node

async function getPairsByToken(addr: string) {
    const addrLower = addr.toLowerCase()
    const post_json = String.raw`{"operationName":"tokens","variables":{},"query":"fragment TokenFields on Token {\n  id\n  name\n  symbol\n  derivedETH\n  tradeVolume\n  tradeVolumeUSD\n  untrackedVolumeUSD\n  totalLiquidity\n  txCount\n  __typename\n}\n\nquery tokens {\n  tokens(where: {id: \"${addrLower}\"}) {\n    ...TokenFields\n    __typename\n  }\n  pairs0: pairs(where: {token0: \"${addrLower}\"}, first: 50, orderBy: reserveUSD, orderDirection: desc) {\n    id\n    __typename\n  }\n  pairs1: pairs(where: {token1: \"${addrLower}\"}, first: 50, orderBy: reserveUSD, orderDirection: desc) {\n    id\n    __typename\n  }\n}\n"}`
    const res = await axios.post(
        UNI_GRAPH_NODE,
        post_json
    )
    const data = res.data.data
    const pairs0 = data.pairs0 as IPair[]
    const pairs1 = data.pairs1 as IPair[]
    return pairs0.concat(pairs1).map(item=> item.id)
}

export async function getETHPairByToken(addr: string) {
    const addrLower = addr.toLowerCase()
    const pairs = await getPairsByToken(addrLower)

    let taskList = []
    for (const pair of pairs) {
        const post_json = String.raw`{"operationName":"pairs","variables":{"allPairs":["${pair}"]},"query":"fragment PairFields on Pair {\n  id\n  txCount\n  token0 {\n    id\n    symbol\n    name\n    totalLiquidity\n    derivedETH\n    __typename\n  }\n  token1 {\n    id\n    symbol\n    name\n    totalLiquidity\n    derivedETH\n    __typename\n  }\n  reserve0\n  reserve1\n  reserveUSD\n  totalSupply\n  trackedReserveETH\n  reserveETH\n  volumeUSD\n  untrackedVolumeUSD\n  token0Price\n  token1Price\n  createdAtTimestamp\n  __typename\n}\n\nquery pairs($allPairs: [Bytes]!) {\n  pairs(where: {id_in: $allPairs}, orderBy: trackedReserveETH, orderDirection: desc) {\n    ...PairFields\n    __typename\n  }\n}\n"}`
        const task = axios.post(
            UNI_GRAPH_NODE,
            post_json
        )
        taskList.push(task)
    }
    const resList = await Promise.all(taskList)

    let pairInfoList = []
    for (const res of resList) {
        const data = res.data.data
        pairInfoList.push(data.pairs[0])
    }

    const ETHPair = pairInfoList.filter( item => {
        const {token0, token1} = item
        return [token0.symbol, token1.symbol].includes("WETH")
    })

    if (ETHPair.length === 0) {
        console.warn('The token does not have any liquidity pair.')
    }

    if (ETHPair.length > 1) {
        console.warn('The token has more than one pair.\please check it if this is not what you want.', ETHPair)
    }

    return ETHPair[0]
}

export async function getTxByPair(addr: string, graphql: string) {
    console.log(addr);
    console.log(graphql);
    
    const addrLower = addr.toLowerCase()
    const post_json = String.raw`{"operationName":null,"variables":{"allPairs":["${addrLower}"]},"query":"query ($allPairs: [Bytes]!) {\n  mints(first: 20, where: {pair_in: $allPairs}, orderBy: timestamp, orderDirection: desc) {\n    transaction {\n      id\n      timestamp\n      __typename\n    }\n    pair {\n      token0 {\n        id\n        symbol\n        __typename\n      }\n      token1 {\n        id\n        symbol\n        __typename\n      }\n      __typename\n    }\n    to\n    liquidity\n    amount0\n    amount1\n    amountUSD\n    __typename\n  }\n  burns(first: 20, where: {pair_in: $allPairs}, orderBy: timestamp, orderDirection: desc) {\n    transaction {\n      id\n      timestamp\n      __typename\n    }\n    pair {\n      token0 {\n        id\n        symbol\n        __typename\n      }\n      token1 {\n        id\n        symbol\n        __typename\n      }\n      __typename\n    }\n    sender\n    liquidity\n    amount0\n    amount1\n    amountUSD\n    __typename\n  }\n  swaps(first: 999, where: {pair_in: $allPairs}, orderBy: timestamp, orderDirection: desc) {\n    transaction {\n      id\n      timestamp\n      __typename\n    }\n    id\n    pair {\n      token0 {\n        id\n        symbol\n        __typename\n      }\n      token1 {\n        id\n        symbol\n        __typename\n      }\n      __typename\n    }\n    amount0In\n    amount0Out\n    amount1In\n    amount1Out\n    amountUSD\n    to\n    __typename\n  }\n}\n"}`

    const res = await axios.post(
        graphql,
        post_json
    )
    const data = res.data.data
    return data
}

/**
 * Pure
 */
export function fixed(n: string) {
    let n_str = parseFloat(n).toFixed(6)
    n_str = n_str.replace(/(?:\.0*|(\.\d+?)0+)$/,'$1')
    return n_str
}

export function parseWETHtoETH(name: string) {
    if (name === 'WETH') {
        return 'ETH'
    }
    return name
}


export { usePrice } from './price'